package com.zhonglian.elisa.customer;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.Nullable;

/**
 * Create ：Yx
 * 曲线图源码
 */
public class CurveView extends View {
    private List<WaveConfigData> mWaves;// 数值集合
    private int mCoordinateYCount = 8;
    private float[] mCoordinateXValues = new float[]{0f, 5f, 10f, 15f, 20f, 25f, 30f}; //X 坐标轴上的数值
    private float[] mCoordinateYValues;// Y 坐标轴上的数值间隔,动态计算空间
    // 坐标的单位
    private String mXUnit = "横";// X 轴的单位
    private String mYUnit = "竖";// Y 轴的单位
    private float mGlobalMaxValue;//所有曲线中所有数据中的最大值， 用于确认是否需要调整坐标系
    private Paint mCoordinatorPaint;
    private Paint mTextPaint;
    private Paint mWrapPaint;  // 坐标轴上描述性文字的空间大小
    private int mTopUnitHeight;// 顶部Y轴单位高度
    private int mBottomTextHeight;// X轴底部字体的高度
    private int mLeftTextWidth;// Y轴左边字体的宽度
    private int mGridWidth, mGridHeight;// 网格尺寸
    private float mAnimProgress;


    public CurveView(Context context) {
        this(context, null);
    }

    public CurveView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CurveView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
        post(new Runnable() {
            @Override
            public void run() {
                showAnimator();
            }
        });
    }


    // 初始化数据集合的容器
    private void init() {
        mWaves = new ArrayList<>();    // 坐标系的单位
        mBottomTextHeight = dp2px(40);// X轴底部字体的高度
        mLeftTextWidth = mBottomTextHeight;// Y轴左边字体的宽度
        mTopUnitHeight = dp2px(30);// 顶部Y轴的单位
        // 初始化坐标轴Paint
        mCoordinatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        mCoordinatorPaint.setColor(Color.LTGRAY);
        // 初始化文本Paint
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        mTextPaint.setColor(Color.GRAY);
        mTextPaint.setTextSize(sp2px(12));
        // 初始化曲线Paint
        mWrapPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
        mWrapPaint.setPathEffect(new CornerPathEffect(200f));
        setWaveData(Color.parseColor("#FF0000"), false, 0f, 10f, 30f, 54f, 30f, 100f, 10f);

    }

    /**
     * 动画
     */
    public void showAnimator() {
        ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f).setDuration(1000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mAnimProgress = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        animator.start();
    }

    /**
     * 数据初始
     * * @param color 颜色
     * * @param isCoverRegion 是否是绘制阴影区域曲线图 false绘制曲线，true绘制阴影曲线
     * * @param values  数据数组
     */
    public void setWaveData(int color, boolean isCoverRegion, float... values) {
        mWaves.add(new WaveConfigData(color, isCoverRegion, values));
        inItCalculationY(mWaves.get(0).values);//计算Y刻度间隔
        invalidate();
    }


    /**
     * 根据 （ 给出的n组数据中）的最大值，计算Y坐标间隔
     */
    private void inItCalculationY(float... values) {
        // 根据value的值去计算纵坐标的数值
        float maxValue = 0;
        for (float value : values) {
            maxValue = Math.max(maxValue, value);//返回一组数中的最大值
        }
        if (maxValue < mGlobalMaxValue) return;
        mGlobalMaxValue = maxValue;//赋值一组数中的最大值
        // 保证网格的数值都为 5 的倍数
        float gridValue = mGlobalMaxValue / (mCoordinateYCount - 1);
        if (gridValue % 5 != 0) {
            gridValue += 5 - (gridValue % 5);//例100%5 =4 5-4=1  gridValue =100/7=14 得14+=5-4 gridValue=15
        }
        // 给纵坐标的数值赋值
        mCoordinateYValues = new float[mCoordinateYCount];//Y空间15
        for (int i = 0; i < mCoordinateYCount; i++) {
            mCoordinateYValues[i] = i * gridValue;
        }
    }


    @Override
    protected void onDraw(Canvas canvas) {
        //addWave(Color.parseColor("#8596dee9"), true, 0f, 15f, 10f, 10f, 40f, 20f, 5f);
        drawCoordinate(canvas);//绘制X.Y坐标
        drawWrap(canvas);//绘制曲线
    }


    /**
     * 绘制横纵X.Y坐标
     */
    private void drawCoordinate(Canvas canvas) {
        Point start = new Point();
        Point stop = new Point();
        // 1. 绘制横轴线和纵坐标单位
        int xLineCount = mCoordinateYValues.length;
        mGridHeight = (getHeight() - getPaddingTop() - getPaddingBottom() - mBottomTextHeight - mTopUnitHeight) / (xLineCount - 1);
        for (int i = 0; i < xLineCount; i++) {
            start.x = getPaddingLeft() + mLeftTextWidth;
            start.y = getHeight() - getPaddingBottom() - mBottomTextHeight - mGridHeight * i;
            stop.x = getRight() - getPaddingRight();
            stop.y = start.y;
            // 绘制横轴线
            canvas.drawLine(start.x, start.y, stop.x, stop.y, mCoordinatorPaint);
            // 绘制纵坐标单位
            if (i == 0) continue;
            String drawText = String.valueOf((int) mCoordinateYValues[i]);
            Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt();
            float offsetY = ((fontMetrics.bottom - fontMetrics.top) / 2 + fontMetrics.bottom) / 2;
            float baseLine = start.y + offsetY;
            float left = getPaddingLeft() + mLeftTextWidth / 2 - mTextPaint.measureText(drawText) / 2;
            canvas.drawText(drawText, left, baseLine, mTextPaint);
            // 绘制Y轴单位
            if (i == xLineCount - 1) {
                drawText = mYUnit;
                baseLine = getPaddingTop() + mTopUnitHeight / 2;
                canvas.drawText(drawText, left, baseLine, mTextPaint);
            }
        }
        // 2. 绘制纵轴线和横坐标单位
        int yLineCount = mCoordinateXValues.length;
        mGridWidth = (getWidth() - getPaddingLeft() - getPaddingRight() - mLeftTextWidth) / (yLineCount - 1);
        for (int i = 0; i < yLineCount; i++) {
            start.x = getPaddingTop() + mLeftTextWidth + mGridWidth * i;
            start.y = getPaddingTop() + mTopUnitHeight;
            stop.x = start.x;
            stop.y = getHeight() - mBottomTextHeight - getPaddingBottom();
            // 绘制纵轴线
            canvas.drawLine(start.x, start.y, stop.x, stop.y, mCoordinatorPaint);
            // 绘制横坐标单位
            String drawText = String.valueOf((int) mCoordinateXValues[i]);
            Paint.FontMetricsInt fontMetrics = mTextPaint.getFontMetricsInt();
            float offsetY = ((fontMetrics.bottom - fontMetrics.top) / 2 + fontMetrics.bottom) / 2;
            float baseLine = getHeight() - getPaddingBottom() - mBottomTextHeight / 2 + offsetY;
            float left = start.x - mTextPaint.measureText(drawText) / 2;
            // 绘制X轴单位
            if (i == 0) {
                drawText = mXUnit;
                left = getPaddingLeft() + mLeftTextWidth / 2 - mTextPaint.measureText(drawText) / 2;
            }
            canvas.drawText(drawText, left, baseLine, mTextPaint);
        }
    }

    /**
     * 绘制曲线
     */
    private void drawWrap(Canvas canvas) {
        canvas.clipRect(new RectF(mLeftTextWidth, getPaddingTop() + mTopUnitHeight, (getRight() - getPaddingRight()) * mAnimProgress, getHeight() - getPaddingBottom() - mBottomTextHeight));
        float yHeight = mGridHeight * (mCoordinateYCount - 1);
        for (WaveConfigData wave : mWaves) {
            Path path = new Path();
            path.moveTo(0, getHeight());
            float maxY = mCoordinateYValues[mCoordinateYCount - 1];// Y轴坐标的最大值
            for (int index = 1; index < wave.values.length; index++) {
                path.lineTo(mLeftTextWidth + mGridWidth * index, getHeight() - getPaddingBottom() - mBottomTextHeight - yHeight * (wave.values[index] / maxY));
            }
            if (wave.isCoverRegion) {
                mWrapPaint.setStyle(Paint.Style.FILL);
                path.lineTo(getRight() - getPaddingRight(), getHeight());
                path.close();
            } else {
                mWrapPaint.setStyle(Paint.Style.STROKE);
                mWrapPaint.setStrokeWidth(10);
            }
            mWrapPaint.setColor(wave.color);
            canvas.drawPath(path, mWrapPaint);
        }
    }


    private int dp2px(float dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
    }

    private int sp2px(float sp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
    }

    public static class WaveConfigData {
        int color;
        boolean isCoverRegion;
        float values[];

        public WaveConfigData(int color, boolean isCoverRegion, float[] values) {
            this.color = color;
            this.isCoverRegion = isCoverRegion;
            this.values = values;
        }
    }
}
